<?php
/**
 * @author GhostWei
 * @date Sep 29, 2012
 */
class translator_api_bing extends translator_abstract {
	
	protected $_authUrl = 'https://datamarket.accesscontrol.windows.net/v2/OAuth2-13/';
	protected $_scopeUrl = 'http://api.microsofttranslator.com';
	protected $_translateUrl = 'http://api.microsofttranslator.com/V2/Http.svc/Translate';	
	protected $_namespace = 'translator-bing';
	protected $_concept = null;
	
	public function __construct() {
		$this->_concept = new system_setting_translator('bing');
		parent::__construct();
	}
	
	
	public function translate() {
		$response = new translator_response();
		try {
			$concept = $this->getConcept('bing');
		} catch (Exception $e) {
			return $response->setError($e->getMessage());
		}
		try {
			$token = $this->getAccessToken();
		} catch (Exception $e) {
			return $response->setError($e->getMessage());
		}
		$params = array(
				'appId' => 'Bearer ' . $token->access_token,
				'from' => $this->getFrom(),
				'to' => $this->getTo(),
				'text' => $this->getText(),
				'contentType' => 'text/plain'
		);
		$data = $this->get($this->_translateUrl . '?' . http_build_query($params));
		if(preg_match('/^<string[^>]+>(.*)<\/string>$/i', $data, $match)) {
			return $response->setResult($match[1]);
		}
		if(preg_match('/<p>Message:([^<]+)<\/p>/i', $data, $match)) {
			return $response->setError(trim($match[1]));
		}
		return $response->setError($response);
	}
	
	protected function _accessToken() {
		$params = array(
				'grant_type' => 'client_credentials',
				'scope' => $this->_scopeUrl,
				'client_id' => $this->_concept->getAppId(),
				'client_secret' => $this->_concept->getAppKey()
		);
		$json = $this->parseJson($this->post($this->_authUrl, http_build_query($params)));
		if(isset($json->error)) {
			throw new translator_exception('Get Access Token error: ' . $json->error);
		}
		$json->expires = time() + $json->expires_in;
		return $json;
	}

	protected function getAccessToken() {
		$options = array();
		$options['dir'] = _DIRECTORY_VAR . DIRECTORY_SEPARATOR . 'cache';
		$options['suffix'] = 'accessToken';
		
		$cache = new system_cache_file($options);
		$cache->setOptions($options);
		if(!($data = $cache->load($this->_namespace))) {
			try {
				$data = $this->_accessToken();
				$cache->setOptions($options);
				$cache->save($this->_namespace, $data);
			} catch (Exception $e) {
				throw $e;
			}
		}
		return $data;
	}

	protected function parseJson($data) {
		try {
			$json = @json_decode($data);
		} catch (Exception $e) {
			return new stdClass();
		}
		return is_object($json) ? $json : new stdClass();
	}
}
